package me.duzhi.ilog.cms.controller;

import com.alibaba.fastjson.JSONObject;
import com.jfinal.aop.Before;
import com.jfinal.ext.interceptor.POST;
import com.jfinal.kit.PathKit;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.IAtom;
import com.jfinal.render.FreeMarkerRender;
import com.jfinal.upload.UploadFile;
import freemarker.template.TemplateException;
import io.jpress.Consts;
import io.jpress.core.BaseFrontController;
import io.jpress.core.Jpress;
import io.jpress.interceptor.InterUtils;
import io.jpress.interceptor.UCodeInterceptor;
import io.jpress.interceptor.UserInterceptor;
import io.jpress.model.*;
import io.jpress.model.query.MappingQuery;
import io.jpress.model.query.OptionQuery;
import io.jpress.model.query.TaxonomyQuery;
import io.jpress.model.query.UserQuery;
import io.jpress.notify.email.Email;
import io.jpress.router.RouterMapping;
import io.jpress.template.TemplateManager;
import io.jpress.utils.AttachmentUtils;
import io.jpress.utils.CookieUtils;
import io.jpress.utils.EncryptUtils;
import io.jpress.utils.FileUtils;
import java.io.File;
import me.duzhi.ilog.cms.plugins.crop.ImageCut;
import me.duzhi.ilog.cms.validate.ContentValidator;

import java.io.IOException;
import java.io.StringWriter;
import java.math.BigInteger;
import java.sql.SQLException;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import static io.jpress.utils.AttachmentUtils.dateFormat;

/**
 * 用户中心
 *
 * @author ashang.peng@aliyun.com
 * @date 十二月 21, 2016
 */
@RouterMapping(url = "/member")
public class _UserController extends BaseFrontController {

  public void index() {
    String action = getPara();
    render("_user_" + action + ".html");
  }

  @Before({UserInterceptor.class, POST.class, ContentValidator.class, UCodeInterceptor.class})
  public void save() {
    String option = getPara("option");
    if (isMultipartRequest()) {
      setAvatar();
      return;
    } else if ("post".equals(option)) {
      if (putPost()) {
        return;
      }
    } else if ("user".equals(option)) {
      setUser();
      return;
    } else if ("oppass".equals(option)) {
      String pass1 = getPara("pass1");
      String pass2 = getPara("pass2");
      if (StrKit.notBlank(pass1) && pass1.equals(pass2)) {
        User user = UserQuery.me().findById(getLoginedUser().getId());
        user.setPassword(EncryptUtils.encryptPassword(pass1, user.getSalt()));
        user.update();
        renderAjaxResult("", 1);
      } else {
        renderAjaxResult("新密码不对~请修改后重试", 0);
      }
      return;
    }
    renderAjaxResult("操作错误", 1);
  }

  private void setUser() {
    User user = getModel(User.class);
    User _user = getLoginedUser();
    //保证更新的是当前登录的用户
    user.setId(_user.getId());
    user.update();
    renderAjaxResult("", 1);
    return;
  }

  @Before(POST.class)
  public void resetPassword() throws IOException, TemplateException {
    String mail = getPara("mail");
    User user = UserQuery.me().findUserByEmail(mail);
    if (user != null) {
      String password = EncryptUtils.generateSalt(7);
      user.setPassword(EncryptUtils.encryptPassword(password, user.getSalt()));
      user.update();
      setAttr("password", password);
      String result = renderToString(
          TemplateManager.me().currentTemplatePath() + "/email/resetPassword.html");
      Email.create().subject("重置密码").content(result).to(mail).send();
      renderAjaxResult("重置成功，请到邮箱获取最新密码。", 0);
    } else {
      renderAjaxResult("你的邮箱不正确", 1);
    }
  }

  private String renderToString(String templatePath) throws IOException, TemplateException {
    freemarker.template.Configuration configuration = FreeMarkerRender.getConfiguration();
    freemarker.template.Template template = configuration.getTemplate(templatePath);
    //最关键在这里，不使用与文件相关的Writer
    StringWriter stringWriter = new StringWriter();
    HashMap data = new HashMap();
    Enumeration writer = getRequest().getAttributeNames();
    while (writer.hasMoreElements()) {
      String e = (String) writer.nextElement();
      data.put(e, getRequest().getAttribute(e));
    }
    Map<String, Object> jpTags = new HashMap<String, Object>();
    jpTags.putAll(Jpress.jpressTags);
    for (Enumeration<String> attrs = getRequest().getAttributeNames(); attrs.hasMoreElements(); ) {
      String attrName = attrs.nextElement();
      if (attrName.startsWith("jp.")) {
        jpTags.put(attrName.substring(3), getRequest().getAttribute(attrName));
      } else {
        data.put(attrName, getRequest().getAttribute(attrName));
      }
    }
    data.put("jp", jpTags);
    template.process(data, stringWriter);
    return stringWriter.toString();
  }

  private boolean putPost() {
    if (!validateCaptcha("_register_captcha")) { //
      //renderForRegister("not validate captcha", Consts.ERROR_CODE_NOT_VALIDATE_CAPTHCHE);
      renderAjaxResult("您输入的验证码不对", 0);
      return true;
    }
    Content content = getModel(Content.class);
    if (content == null) {
      renderAjaxResult("没有创建对应的服务信号", 0);
      return true;
    }
    if (content.getTitle() == null) {
      renderAjaxResult("没有填写标题", 0);
      return true;
    }
    String demo = getPara("demo");
    String downloadURL = getPara("downloadURL");
    if (StrKit.isBlank(content.getText()) || content.getText().length() < 100) {
      renderAjaxResult("没有填写内容或内容字数过少", 0);
      return true;
    }
    if (StrKit.isBlank(demo) && "dm".equals(content.getModule())) {
      renderAjaxResult("演示地址为空", 0);
      return true;
    }
    if (StrKit.isBlank(downloadURL) && "dm".equals(content.getModule())) {
      renderAjaxResult("没有提供下载地址", 0);
      return true;
    }
    if (StrKit.isBlank(content.getText()) || content.getText().length() < 100) {
      renderAjaxResult("没有填写内容或内容字数过少", 0);
      return true;
    }
    boolean result =
        new Db().tx(new IAtom() {
          @Override
          public boolean run() throws SQLException {
            content.setCreated(new Date());
            User user = getLoginedUser();
            content.setUserId(user.getId());
            content.setStatus(Content.STATUS_DRAFT);
            content.save();
            BigInteger taxonomys = getParaToBigInteger("taxonomys");
            Taxonomy taxonomy = TaxonomyQuery.me().findById(taxonomys);
            if (taxonomy == null) {
              renderAjaxResult("没有选择分类", 0);
              return false;
            }
            //			OptionQuery.me().saveOrUpdate("downloads",downloadURL);
            if ("dm".equals(content.getModule())) {
              Metadata metadata = new Metadata();
              metadata.setMetaKey("demo");
              metadata.setMetaValue(downloadURL);
              metadata.setObjectType(Content.METADATA_TYPE);
              metadata.setObjectId(content.getId());
              metadata.save();
              Metadata metadata1 = new Metadata();
              metadata1.setMetaKey("downloads");
              metadata1.setMetaValue(downloadURL);
              metadata1.setObjectType(Content.METADATA_TYPE);
              metadata1.setObjectId(content.getId());
              metadata1.save();
            }
            MappingQuery.me().doBatchUpdate(content.getId(), new BigInteger[]{taxonomy.getId()});
            renderAjaxResult("提交成功，等待审核，请稍后.....", 1);
            return true;
          }
        });
    if (!result) {
      renderAjaxResult("提交失败，请稍后重试", 1);
      return true;
    }
    return false;
  }

  private void setAvatar() {
    String webRoot = PathKit.getWebRootPath();
    UploadFile file = getFile();
    if (file != null) {
      String newPath = AttachmentUtils.moveFile(file);
      String avatar_src = getPara("avatar_data");
      JSONObject joData = (JSONObject) JSONObject.parse(avatar_src);
      // 用户经过剪辑后的图片的大小
      Integer x = joData.getInteger("x");
      Integer y = joData.getInteger("y");
      Integer w = joData.getInteger("width");
      Integer h = joData.getInteger("height");
      ImageCut.abscut(webRoot + newPath, webRoot + newPath, x, y, w, h);
      File file1 = new File(webRoot + newPath);
      AttachmentUtils.ftpUpload(file1.getParentFile().getName(), file1);
      User user = getLoginedUser();
      String upload_read_path = OptionQuery.me().findValue("upload_read_path");
      if (upload_read_path != null) {
        String path = newPath.substring(newPath.indexOf(dateFormat.format(new Date())));
        newPath = upload_read_path + path;
        newPath = newPath.replaceAll("\\\\", "/");
      }
      Attachment attachment = new Attachment();
      attachment.setUserId(user.getId());
      attachment.setCreated(new Date());
      attachment.setTitle(file.getOriginalFileName());
      attachment.setPath(newPath.replace("\\", "/"));
      attachment.setSuffix(FileUtils.getSuffix(file.getFileName()));
      attachment.setMimeType(file.getContentType());
      attachment.save();
      user.setAvatar(attachment.getPath());
      user.update();
    }
    renderAjaxResult("上传成功", 1, getLoginedUser().getAvatar());
    return;
  }

  public void loginout() {
    CookieUtils.remove(this, Consts.COOKIE_LOGINED_USER);
    redirect("/?loginout");
  }

  public void later() {
    String returnUrl = CookieUtils.get(this, "redirecturl_Referer");
    CookieUtils.remove(this, "redirecturl_Referer");
    if (returnUrl == null) {
      returnUrl = "/";
    }
    setAttr("returnUrl", returnUrl);
    render("_user_later.html");
  }

}
